package Shuffle;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 主要Poke類別，有花色，點數，跟預設牌大小
 * @author QK
 */
public class Poke {
	/**
	 * 牌的花色
	 */
	public String color;	
	/**
	 * 牌的點數
	 */
	public String number;	
	/**
	 * 牌的大小
	 */
	public int cardOrder;		
	/**
	 * 總共52張牌，給底下的發牌類別使用
	 */
	protected int totalCards = 52;
	/**
	 * 預設花色，小到大排序
	 */
	public static final String cardOfColor[]  = { "梅花", "磚塊", "愛心", "黑桃" };
	/**
	 * 預設點數，小到大排序
	 */
	public static final String cardOfNumber[] = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
	
	public static final String cardOfSanke[][] = {{"A","2","3","4","5"}, {"3","4","5","6","7"},
												  {"4","5","6","7","8"}, {"5","6","7","8","9"},
												  {"6","7","8","9","10"},{"7","8","9","10","J"},
												  {"8","9","10","J","Q"},{"9","10","J","Q","K"},
												  {"10","J","Q","K","A"},{"2","3","4","5","6"}};
	
	/**
	 * 這會跟allCardOrder產生對應，方便查詢
	 */
	public static final String allCards[] = new String[52];
	/**
	 * 一副牌的基本大小,key是花色+點數，取得value是該牌的大小
	 */
	private static Map< String,Integer> allCardOrder;
	
	

	/**
	 * 使用cardOfNumber與cardOfColor小到大特性，來產生這副牌的基本大小
	 * 例:梅3 = 0、磚3 = 1，以此類推
	 */
	public void setCardOrder(){
		//order最小點數，0開始起跳，從最小的牌開始放
		int order = 0;
		allCardOrder = new HashMap<String, Integer>();
		for(int cardsNum = 0 ; cardsNum < cardOfNumber.length ; cardsNum++){
			for(int colorNum = 0 ; colorNum < cardOfColor.length ; colorNum++){
				allCardOrder.put(cardOfColor[colorNum]+cardOfNumber[cardsNum], order );
				allCards[order] = cardOfColor[colorNum]+cardOfNumber[cardsNum];
				order++;
			}
		}
	}
	
	/**
	 * @return 所有牌的大小順序
	 */
	public Map<String, Integer> getCardOrder(){
		return allCardOrder;
	}
	
	/**
	 * 玩家拿到一副牌，幫他小到大排序
	 * @param cardList 一副牌的List
	 * @return 回傳排序好的牌
	 */
	public List<Poke> cardSort(List<Poke> cardList){
		for(int num = 0 ; num < cardList.size() ; num++){
			for(int check = 0 ; check <cardList.size() ; check++){
				//Poke card[] = swapCard(cardList.get(num),cardList.get(check));
				Poke card[] = swapCard(cardList.get(num),cardList.get(check));
				cardList.set(num, card[0]);
				cardList.set(check, card[1]);
			}
		}
		return cardList;
	}
	
	/**
	 * 使用MAP方式，前面儲放牌型、後面儲存牌的大小
	 * 減少使用for迴圈尋找的方式
	 */
	public static Poke[] swapCard(Poke card1,Poke card2){
		String cardString1 = card1.color+card1.number;
		String cardString2 = card2.color+card2.number;
		//第一張牌的點數大小
		int cardOrder1 = allCardOrder.get(cardString1);	
		//第二張牌的點數大小
		int cardOrder2 = allCardOrder.get(cardString2);	

		Poke[] changePoke = new Poke[2];
		if(cardOrder1 >cardOrder2){
			changePoke[0] = card1;
			changePoke[1] = card2;
		}else{
			changePoke[0] = card2;
			changePoke[1] = card1;
		}
		return changePoke;
	}
	
	/**
	 * 秀出所有玩家的對子
	 * @param player
	 */
	public void showPlayerPair(Player player){
		Player[] players = player.getPlayers();		
		for(int index = 0 ; index< player.getPleyerNumber();index++){
			List<Poke> pokeList =  players[index].getListPoke(index);
			System.out.print(players[index].getName()+"-");
			findPair(pokeList);
			System.out.println();
		}
	}
	
	/**
	 * 傳入一組牌的PokoList，找出對子
	 * @param pokeList
	 */
	public void findPair(List<Poke> pokeList){
		//關鍵點，因為牌已經排序過
		//為了減少for迴圈與判斷改用自動位移下一張牌來尋找對子
		//之後再扣掉位移的次數
		for(int index = 0 ; index < pokeList.size()-1 ; index++){
			Poke a = pokeList.get(index);
			Poke b = pokeList.get(++index);
			if(a.number.equals(b.number) && !a.color.equals(b.color)){
				System.out.print(a.color+a.number+" "+b.color+b.number+"\t");
				//pokeList.remove(a);
				//pokeList.remove(b);
			}
			--index;	
		}
	}
	
	/**
	 * 秀出玩家所有可能的三張
	 * @param player
	 */
	public void showPlayerThree(Player player){
		Player[] players = player.getPlayers();		
		for(int index = 0 ; index< player.getPleyerNumber();index++){
			List<Poke> pokeList =  players[index].getListPoke(index);
			System.out.print(players[index].getName()+"-");
			findThree(pokeList);
			System.out.println();
		}
	}
	
	/**
	 * 傳入一組牌的PokoList，找出三張
	 * @param pokeList
	 */
	public void findThree(List<Poke> pokeList){
		for(int index = 0 ; index < pokeList.size()-2 ; index++){
			Poke a = pokeList.get(index);
			Poke b = pokeList.get(++index);
			Poke c = pokeList.get(++index);
			if( a.number.equals(b.number) && b.number.equals(c.number) 
			&& !a.color.equals(b.color) && !b.color.equals(c.color) ){
				System.out.print(a.color+a.number+" "+b.color+b.number+" "+c.color+c.number+"\t");
			}
			index-=2;
		}
	}
	
	/**
	 * 秀出玩家所有可能的葫蘆
	 * @param player
	 */
	public void showPlayerFullHouse(Player player){
		Player[] players = player.getPlayers();		
		for(int index = 0 ; index< player.getPleyerNumber();index++){
			List<Poke> pokeList =  players[index].getListPoke(index);
			System.out.print(players[index].getName()+"-");
			findFullHouse(pokeList);
			System.out.println();
		}
	}
	
	/**
	 * 傳入一組牌的PokoList，找出葫蘆
	 * @param pokeList
	 */
	public void findFullHouse(List<Poke> pokeList){
		for(int index = 0 ; index < pokeList.size()-2 ; index++){
			Poke a = pokeList.get(index);
			Poke b = pokeList.get(++index);
			Poke c = pokeList.get(++index);
			if( a.number.equals(b.number) && b.number.equals(c.number) 
			&& !a.color.equals(b.color) && !b.color.equals(c.color) ){
				pokeList.remove(a);pokeList.remove(b);pokeList.remove(c);
				for( int index2 = 0 ; index2 < pokeList.size()-1 ; index2++){
					Poke d = pokeList.get(index2);
					for(int index3 = 1 ; index3 < pokeList.size() ; index3++){
						Poke e = pokeList.get(index3);
						if(d.number.equals(e.number) && !d.color.equals(e.color)){
							System.out.print(a.color+a.number+" "+b.color+b.number+" "+c.color+c.number+" "+
										 	 d.color+d.number+" "+e.color+e.number+"\t");
						}	
					}
				}
				pokeList.add(a);pokeList.add(b);pokeList.add(c);
				//因為移除後，順序亂掉，重新排序
				pokeList = new Poke().cardSort(pokeList);
			}
			index-=2;
		}
	}
	
	/**
	 * 秀出玩家所有可能的四張
	 * @param player
	 */
	public void showPlayerFour(Player player){
		
		Player[] players = player.getPlayers();		
		for(int index = 0 ; index< player.getPleyerNumber();index++){
			List<Poke> pokeList =  players[index].getListPoke(index);
			System.out.print(players[index].getName()+"-");
			findFour(pokeList);
			System.out.println();
		}
	}
	
	/**
	 * 傳入一組牌的PokoList，找出四張
	 * @param pokeList
	 */
	public void findFour(List<Poke> pokeList){
		for(int index = 0 ; index < pokeList.size()-3 ; index++){
			Poke a = pokeList.get(index);
			Poke b = pokeList.get(++index);
			Poke c = pokeList.get(++index);
			Poke d = pokeList.get(++index);
			if( a.number.equals(b.number) && b.number.equals(c.number) 
			&& c.number.equals(d.number) && d.number.equals(a.number)
			&& !a.color.equals(b.color) && !b.color.equals(c.color) 
			&& !c.color.equals(d.color) && !d.color.equals(a.color)){
				System.out.print(a.color+a.number+" "+b.color+b.number+" "+c.color+c.number+" "+d.color+d.number+"\t");
			}
			index-=3;
		}
	}
	
	/**
	 * 秀出玩家所有可能的鐵支
	 * @param player
	 */
	public void showPlayerFourAKing(Player player) {
		Player[] players = player.getPlayers();		
		for(int index = 0 ; index< player.getPleyerNumber();index++){
			List<Poke> pokeList =  players[index].getListPoke(index);
			System.out.print(players[index].getName()+"-");
			System.out.print(pokeList.size()+"-");
			findFourAKing(pokeList);
			System.out.println();
		}
		
	}
	
	/**
	 * 傳入一組牌的PokoList，找出可能的鐵支
	 * @param pokeList
	 */
	public void findFourAKing(List<Poke> pokeList) {
		for(int index = 0 ; index < pokeList.size()-3 ; index++){
			Poke a = pokeList.get(index);
			Poke b = pokeList.get(++index);
			Poke c = pokeList.get(++index);
			Poke d = pokeList.get(++index);
			if( a.number.equals(b.number) && b.number.equals(c.number) 
			&& c.number.equals(d.number) && d.number.equals(a.number)
			&& !a.color.equals(b.color) && !b.color.equals(c.color) 
			&& !c.color.equals(d.color) && !d.color.equals(a.color)){
				pokeList.remove(a); pokeList.remove(b); pokeList.remove(c);pokeList.remove(d);
				for(int index2 = 0 ; index2 < pokeList.size() ; index2++){
					Poke e = pokeList.get(index2);
					System.out.print(a.color+a.number+" "+b.color+b.number+" "
							+c.color+c.number+" "+d.color+d.number+" "+ 
							 e.color+e.number+"\t");
				}
				pokeList.add(a); pokeList.add(b); pokeList.add(c);pokeList.add(d);
				pokeList = new Poke().cardSort(pokeList);
			}
			index-=3;
		}
	}

	/**
	 * 秀出玩家可能的順子
	 * @param player
	 */
	public void showPlayerSnake(Player player) {
		Player[] players = player.getPlayers();		
		for(int index = 0 ; index< player.getPleyerNumber();index++){
			List<Poke> pokeList =  players[index].getListPoke(index);
			System.out.print(players[index].getName()+"-");
			System.out.print(pokeList.size()+"-");
			findSnake(pokeList);
			System.out.println();
		}
	}
	
	/**
	 * 找出一副牌的順子-簡單版
	 * @param pokeList
	 */
	public void findSnake(List<Poke> pokeList) {
		
		String tempCardOfSanke[][] = cardOfSanke;
		for(int index = 0 ; index < tempCardOfSanke.length ; index++){
			//暫存5張的點數
			String card1 = tempCardOfSanke[index][0];
			String card2 = tempCardOfSanke[index][1];
			String card3 = tempCardOfSanke[index][2];
			String card4 = tempCardOfSanke[index][3];
			String card5 = tempCardOfSanke[index][4];
			//5個Poke等待有找出相同點數時
			Poke sankeA = null;
			Poke sankeB = null;
			Poke sankeC = null;
			Poke sankeD = null;
			Poke sankeE = null;
			//確認有5張牌可以組成順子的計數器
			int sankeCount = 0;
			for(int index2 = 0 ; index2 < pokeList.size() ; index2++){
				Poke a = pokeList.get(index2);
				if(a.number.equals(card1) && sankeA == null){
					sankeA = new Poke();
					sankeA = a; sankeCount++;
				}
				if(a.number.equals(card2) && sankeB == null){
					sankeB = new Poke();
					sankeB = a; sankeCount++;
				}
				if(a.number.equals(card3) && sankeC == null){
					sankeC = new Poke();
					sankeC = a; sankeCount++;
				}
				if(a.number.equals(card4) && sankeD == null){
					sankeD = new Poke();
					sankeD = a; sankeCount++;
				}
				if(a.number.equals(card5) && sankeE == null){
					sankeE = new Poke();
					sankeE = a; sankeCount++;
				}	
			}
			//確認有5張連續的牌，可以組成順子，印出來
			if(sankeCount == 5 ){
				System.out.print(sankeA.color+sankeA.number+" "+
								 sankeB.color+sankeB.number+" "+
								 sankeC.color+sankeC.number+" "+
								 sankeD.color+sankeD.number+" "+
								 sankeE.color+sankeE.number+"\t");
			}
		}
		
	}
	
	/**
	 * 秀出玩家的同花順
	 * @param player
	 */
	public void showPlayerSameColorSnake(Player player) {
		Player[] players = player.getPlayers();		
		for(int index = 0 ; index< player.getPleyerNumber();index++){
			List<Poke> pokeList =  players[index].getListPoke(index);
			System.out.print(players[index].getName()+"-");
			System.out.print(pokeList.size()+"-");
			findSameColorSnake(pokeList);
			System.out.println();
		}
	}
	
	/**
	 * 找出一副牌的同花順
	 * @param pokeList
	 */
	public void findSameColorSnake(List<Poke> pokeList) {
		
		String tempCardOfSanke[][] = cardOfSanke;
		for(int index = 0 ; index < tempCardOfSanke.length ; index++){
			String card1 = tempCardOfSanke[index][0];
			String card2 = tempCardOfSanke[index][1];
			String card3 = tempCardOfSanke[index][2];
			String card4 = tempCardOfSanke[index][3];
			String card5 = tempCardOfSanke[index][4];
			
			Poke sankeA = null;
			Poke sankeB = null;
			Poke sankeC = null;
			Poke sankeD = null;
			Poke sankeE = null;
			
			int sankeCount = 0;
			for(int index2 = 0 ; index2 < pokeList.size() ; index2++){
				Poke a = pokeList.get(index2);
				if(a.number.equals(card1) && sankeA == null){
					sankeA = new Poke();
					sankeA = a; sankeCount++;
				}
				if(a.number.equals(card2) && sankeB == null){
					sankeB = new Poke();
					sankeB = a; sankeCount++;
				}
				if(a.number.equals(card3) && sankeC == null){
					sankeC = new Poke();
					sankeC = a; sankeCount++;
				}
				if(a.number.equals(card4) && sankeD == null){
					sankeD = new Poke();
					sankeD = a; sankeCount++;
				}
				if(a.number.equals(card5) && sankeE == null){
					sankeE = new Poke();
					sankeE = a; sankeCount++;
				}	
			}
			
			if(sankeCount == 5 && sankeA.color.equals(sankeB.color)
						       && sankeB.color.equals(sankeC.color)
						       && sankeC.color.equals(sankeD.color)
						       && sankeD.color.equals(sankeE.color)){
				System.out.print(sankeA.color+sankeA.number+" "+
								 sankeB.color+sankeB.number+" "+
								 sankeC.color+sankeC.number+" "+
								 sankeD.color+sankeD.number+" "+
								 sankeE.color+sankeE.number+"\t");
			}
		}
		
	}

	public static void main(String[] args) {

	}
}

